﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using GS1.Tools.Extender;
using GS1.Library;
using SegIdenMovil.Herramientas;
using SegIdenMovil.Entidad;
using SegIdenMovil.Delegate;

namespace SegIdenMovil
{
    public partial class frmComponente : Form
    {
        #region --- Variables y Constantes ---
        public Producto producto { get; set; }

        public Componente componenteSeleccionado { get; set; }

        private ListaComponente listaComponenteEncontrados = null;

        private const string FORMATO_TOTAL_ENCONTRADOS = "Total encontrados: {0}";

        private const string DESCRIPCION = "Descripción";
        #endregion

        #region --- Constructor ---
        public frmComponente()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmComponente_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }
 
        private void btnBuscar_Click(object sender, EventArgs e)
        {
            buscar();
        }

        private void btnGuardar_Click(object sender, EventArgs e)
        {
            guardar();
        }

        private void mnuCancelar_Click(object sender, EventArgs e)
        {
            salir(DialogResult.Cancel);
        }

        private void mnuAceptar_Click(object sender, EventArgs e)
        {
            elegirComponente();
        }

        private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            cambiarEstadoBoton();
        }

        public void estiloListView_DoubleClick(object sender, EventArgs e)
        {
            elegirComponente();
        }
        #endregion

        #region --- Metodos Propio ---
        private void cargarFormulario()
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                this.WindowState = FormWindowState.Maximized;

                // Estableciendo a 0 el texto del total de registros encontrados.
                this.lblTotalRegistros.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, 0);

                // Estableciendo parametros del Combo Criterio
                this.cboCriterio.Items.Add(DESCRIPCION);
                this.cboCriterio.SelectedIndex = 0;

                // Se aplica estilo a listview
                aplicarEstiloGrilla(this.lvwListado, this);

                // Estableciendo focus
                this.txtFiltro.Focus();

            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private bool validarEntradaBusqueda()
        {
            this.txtFiltro.Text = this.txtFiltro.Text.Trim();
            if (this.txtFiltro.Text.Equals(string.Empty))
            {
                Util.CampoNecesario(this.txtFiltro, "Debe ingresar el valor de busqueda", this.Text);
                return true;
            }

            if (this.txtFiltro.TextLength < 3)
            {
                Util.CampoNecesario(this.txtFiltro, "Debe ingresar por lo menos 3 caracteres para realizar la busqueda", this.Text);
                return true;
            }

            return false;
        }

        private void listarComponentes(string criterio,
                                       string valor)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_COMPONENTES;

            operacion.componente = new Componente();
            operacion.componente.descripcion = valor;
            operacion.componente.estado = Constantes.ESTADO_CODIGO_ACTIVO;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Util.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de ListaComponente
            this.listaComponenteEncontrados = contenidoXML.DeserializarTo<ListaComponente>();

            // Mostrar el total de registros encontrados
            this.lblTotalRegistros.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, this.listaComponenteEncontrados.lista.Count);

            // Se agrega muestra el detalle de OC
            this.lvwListado.BeginUpdate();
            this.lvwListado.Items.Clear();

            ListViewItem nuevoItem = null;

            // Cargando listado
            foreach (Componente componente in this.listaComponenteEncontrados.lista)
            {
                nuevoItem = new ListViewItem(componente.descripcion);
                nuevoItem.SubItems.Add(componente.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? 
                                            Constantes.ESTADO_DESCRIPCION_INACTIVO : 
                                            Constantes.ESTADO_DESCRIPCION_ACTIVO);

                this.lvwListado.Items.Add(nuevoItem);
            }

            this.lvwListado.EndUpdate();
        }

        private void buscar()
        {
            string criterio = string.Empty;
            string valor = string.Empty;
            try
            {
                if (validarEntradaBusqueda()) { return; }

                // Estableciendo parametros de filtro
                criterio = this.cboCriterio.SelectedValue.ToString().Equals(Constantes.CODIGO_SELECCIONE) ? string.Empty : this.cboCriterio.SelectedValue.ToString();
                valor = this.txtFiltro.Text;

                // Listar componentes con el criterio y el valor ingresado
                listarComponentes(criterio, valor);

                // Estableciendo focus al caja de texto de busqueda
                this.txtFiltro.Focus();
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
        }

        private bool validarEntrada()
        {
            bool resultado = false;

            this.txtDescripcion.Text = this.txtDescripcion.Text.Trim();

            if (this.txtDescripcion.Text.Equals(string.Empty))
            {
                Util.CampoNecesario(this.txtDescripcion, "Debe ingresar el campo descripción", this.Text);
                return true;
            }

            return resultado;
        }

        private void guardar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntrada()) { return; }

                // Mensaje de confirmacion
                if (!Util.ShowMessageboxPregunta("¿Estas seguro de guardar el componente?", this.Text)) { return; }

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_REGISTRAR_COMPONENTE;

                operacion.componente = new Componente();
                operacion.componente.codigo = Constantes.VALOR_CERO;
                operacion.componente.descripcion = this.txtDescripcion.Text;
                operacion.componente.estado = Constantes.ESTADO_CODIGO_ACTIVO;
                operacion.componente.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Util.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();
                string codigoGenerado = string.Empty;

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    codigoGenerado = operacionResultado.codigoGenerado;
                    this.btnGuardar.Enabled = false;
                    Util.ShowMessageboxInfo("Registro guardado correctamente", this.Text);
                }
                else
                {
                    Util.ShowMessageboxError("No se guardo los datos", this.Text);
                    return;
                }

                // Estableciendo los datos de componente selecionado
                this.componenteSeleccionado = new Componente();
                this.componenteSeleccionado.codigo = codigoGenerado;
                this.componenteSeleccionado.descripcion = this.txtDescripcion.Text;

                // Registrando asociacion producto-componente
                asociarProductoComponente(this.componenteSeleccionado);

                salir(DialogResult.OK);
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
        }

        private bool validarEntradaLista()
        {
            int totalSeleccionados = this.lvwListado.SelectedIndices.Count;

            if (totalSeleccionados <= 0)
            {
                Util.CampoNecesario(this.lvwListado, "Debe selecionar un documento a atender", this.Text);
                return true;
            }

            return false;
        }

        private void elegirComponente()
        {
            int indiceFilaSeleccionada = 0;

            try
            {
                if (validarEntradaLista()) { return; }

                Cursor.Current = Cursors.WaitCursor;

                // Obteniendo indice de fila seleccionado
                indiceFilaSeleccionada = this.lvwListado.SelectedIndices[0];

                // Estableciendo datos del componente seleccionado
                this.componenteSeleccionado = this.listaComponenteEncontrados.lista[indiceFilaSeleccionada];

                if (validarComponenteRepetido())
                {
                    Util.CampoNecesario(this.lvwListado, "Este componente ya se encuentra asociado al producto", this.Text);
                    return;
                }

                // Registrando asociacion producto-componente
                asociarProductoComponente(this.componenteSeleccionado);

                salir(DialogResult.OK);
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private bool validarComponenteRepetido()
        {
            bool resultado = false;

            foreach (Componente componente in this.producto.listaComponente.lista)
            {
                if (componente.codigo.Equals(this.componenteSeleccionado.codigo))
                {
                    resultado = true;
                    break;
                }
            }

            return resultado;
        }

        private void asociarProductoComponente(Componente componente)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_ASOCIAR_PRODUCTO_COMPONENTE;

            operacion.producto = new Producto();
            operacion.producto.codigo = this.producto.codigo;

            operacion.producto.listaComponente = new ListaComponente();
            operacion.producto.listaComponente.lista = new ListPersonalizada<Componente>();
            operacion.producto.listaComponente.lista.Add(componente);

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Util.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

            if ((operacionResultado != null) &&
                (operacionResultado.esOK.Equals(Constantes.SI)))
            {
                Util.ShowMessageboxInfo("Registro guardado correctamente", this.Text);
            }
            else
            {
                Util.ShowMessageboxError("No se guardo los datos", this.Text);
                return;
            }
        }

        private void aplicarEstiloGrilla(ListView lvwListado, Form frmFormulario)
        {
            ListViewExv estiloListView = null;

            lvwListado.FullRowSelect = true;

            estiloListView = new ListViewExv(lvwListado, frmFormulario);
            estiloListView.DoubleClick += new EventHandler(estiloListView_DoubleClick);
            estiloListView.VariarTop -= 5;
            estiloListView.SetGridLines();
        }

        private void cambiarEstadoBoton()
        {
            this.mnuAceptar.Enabled = this.tabControl.SelectedIndex == 0;
        }
        
        private void salir(DialogResult resultado)
        {
            this.DialogResult = resultado;
        }
        #endregion
    }
}